#pragma once

/*The Header files for direct X*/
#include <d3d9.h>
#include <d3dx9.h>
#include <dshow.h>

/*The headers for randomization, math and more*/
#include <time.h>
#include <math.h>
#include <vector>

/*User Defined Headers*/
#include "Camera.h"
#include "Input.h"
#include "DXTimer.h"

/*Link the libraries in code*/
#pragma comment(lib, "d3d9.lib") 
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dxguid.lib")

/*Macro to safely release COM objects*/
#define SAFE_RELEASE(x) if(x) {x->Release(); x = 0;}

/*The structure we will be using for our vertex*/
struct Vertex
{
	/*The position vector for the vertex*/
	D3DXVECTOR3 m_Position;

	/*The normal vector for the vertex*/
	D3DXVECTOR3 m_Normal;

	/*The texture coordinates of the vextex*/
	D3DXVECTOR2 m_UV;

	/*The vertex declarations that we are using for this Vertex, EACH MUST BE RELEASED*/
	static IDirect3DVertexDeclaration9* m_Decl;
};

class Framework
{
	/////////////////////////////////////////////////////////////////////////////////////////////////////
	/*Matrices*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////

	/*The world matrix that incompasses Rotation, Scaling, and Translation in that order*/
	D3DXMATRIX m_WorldMat;

	/*The matrix that transforms a vertex to clip space*/
	D3DXMATRIX m_WorldInverseTransposeMat;

	/*The rotation matrix that handles all rotations*/
	D3DXMATRIX m_RotMat;

	/*The scaling matrix that handles uniform and non uniform scaling*/
	D3DXMATRIX m_ScaMat;

	/*The translation matrix that handles all types of translations*/
	D3DXMATRIX m_TransMat;

	/////////////////////////////////////////////////////////////////////////////////////////////////////
	/*DataStructures and Classes*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////

	/*The lights that we will be using*/
	D3DLIGHT9 m_Light;

	/*The materials that we will be using not within any object*/
	D3DMATERIAL9 m_MaterialOrange;
	D3DMATERIAL9 m_MaterialNorm;

	/*Presentation parameters to create the window for direct x correctly*/
	D3DPRESENT_PARAMETERS m_D3Dpp;

	/*The camera we will be using in our framework*/
	Camera m_Cam;

	/*The timer used to manipulate and calculate DT*/
	DXTimer timer;

	/////////////////////////////////////////////////////////////////////////////////////////////////////
	/*VECTORS (Both 2D, 3D and potentially Quaternions*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////	

	/////////////////////////////////////////////////////////////////////////////////////////////////////
	/*Normal Data Types that are ordered from the Highest to lowest in bit size*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////

	/*The light's constant attenuation (x^0)*/
	float m_LightAttenConst;

	/*The light's linear attenuation (x^1)*/
	float m_LightAttenLinear;

	/*The light's Quadratic attenuation (x^2)*/
	float m_LightAttenQuad;

	/*The frames per second that our game is running*/
	float m_Fps;

	/*The Milliseconds per frame variable that we are running*/
	float m_MillSpf;

	/*The time that has passed from one frame to the next*/
	float m_DT;

	/*The BehaviorFlags of our device, Can be used to determine device capabilities dynamically*/
	DWORD m_DevBehaviorFlags;

	/*The width of the window for resizing*/
	int m_Width;

	/*The height of the window for resizing*/
	int m_Height;

	/////////////////////////////////////////////////////////////////////////////////////////////////////
	/*Pointers and Handles*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////

	/*Handle to our Window to create some of the COM objects*/
	HWND m_hWnd;

	/*The Direct3D object that creates all other COM objects, MUST BE RELEASED*/
	IDirect3D9* m_pD3DObject;

	/*The Direct3D Device that will Render our scene for us, MUST BE RELEASED*/
	IDirect3DDevice9* m_pD3DDevice;

	/*Effect files that we have and will be using in our scene, EACH MUST BE RELEASED*/
	ID3DXEffect* m_pD3DEffect;//effect 1

	/*The Buffer used to output whether we had an error loading our fx file, MUST BE RELEASED*/
	ID3DXBuffer* m_pD3DEffectError;

	/*The Handles to the Techniques We are using within the shaders*/
	D3DXHANDLE m_hD3DEffectTechnique;

	/*The Handles to the Variables We are using within the shaders*/
	//D3DXHANDLE m_hShaderVar;

	/*The meshes that we will be using in our entire game/Framework not within any object, EACH MUST BE RELEASED*/
	ID3DXMesh* m_pSphereMesh; // mesh 1

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/*The Polygon mesh to represent Luigi's world space position*/
	ID3DXMesh* m_pLuigiMesh;
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*remove at later point in time

	/*The textures that we will be using in our entire game/Framework not within any object, EACH MUST BE RELEASED*/
	IDirect3DTexture9* m_Grass0Texture;	//Texture 1

	/*The Font Object used to display things on the screen to the user, EACH OBJECT MUST BE RELEASED*/
	ID3DXFont* m_Font;

	/*The pointer to the Input object*/
	Input* m_Input;

	/*The pointer to the bool array in object*/
	bool* m_KeyDown;

	/////////////////////////////////////////////////////////////////////////////////////////////////////
	/*4bytes and Less Variables*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////

	/*Check to see if we are going to use vertical sync*/
	bool m_VSync;

	/*The telling us whether we can use shader version 4*/
	bool m_ShaderVersion4;

	/*The telling us whether we can use shader version 3*/
	bool m_ShaderVersion3;

	/*The telling us whether we can use shader version 2*/
	bool m_ShaderVersion2;

public:
	/*The default Constructor*/
	Framework(void);

	/*The default Destructor*/
	~Framework(void);

	/*The Initialize function to create all of our objects and things that need to be rendered*/
	void Initialize(HWND hWnd, HINSTANCE hInst, bool bWindowed);

	/*The function that will determine what settings we can use to run our game*/
	void DetermineCaps();
	
	/*The function that will create all of the textures that we are going to be using not within any object*/
	void createTextures();

	/*The function that will create all of the materials that we are going to be using not within any object*/
	void createMaterials();

	/*The function that will create all of the lights that we are going to be using not within any object*/
	void createLights();

	/*The function that will create all of the meshes that we are going to be using not within any object*/
	void createMeshes();

	/*The function that will create all of the effects that we are going to be using not within any object*/
	void createEffects();

	/*The function that will make all of the matrices into Identities*/
	void makeIdentityMatrix();
	
	/*The update function that will update all of the math and rendering things we need*/
	void Update();

	/*The function that will draw all of the objects that we need*/
	void Render();

	/*The function that will make sure we resize correctly*/
	void screenResize();

	/*The function that we will use to switch from windowed to full screen and vice versa*/
	void switchingFullScreen(bool enable);

	/*The function that will call all of the other functions needed for when we lose our device*/
	void onLostDevice();

	/*The function that will call all of the other reset functions needed for when we recovered our device*/
	void onResetDevice();
	
	/*The function that checks whether we have lost our device or not*/
	bool lostDevice();

	/*The function that will release everything that needs to be released*/
	void Shutdown();

	/*The function that will release all of the meshes that we are going to be using not within any object*/
	void releaseEffects();
	
	/*The function that will release all of the meshes that we are going to be using not within any object*/
	void releaseMeshes();
	
	/*The function that will release all of the textures that we are going to be using not within any object*/
	void releaseTextures();	

	/*The function that will reset all of the values used within our game/framework*/
	void restart();

	/*The function that will tell us if we have had collision or not*/
	bool checkCollision(int i);
};

